import { Game } from './Game/Game';
import GameManage from './Game/GameManage';
import { GameInitInfo } from './GameInterferce';
import GOBERTS, { FrameInfo } from './GOBERTS';

const gameServer: GOBERTS.GameServer = {
    onDestroyRoom(args: GOBERTS.ActionArgs): void {
        // do something
        let game = GameManage.getGame(args.roomId);
        if (game === undefined) {
            args.SDK.log.error('onDestroyRoom game not exist' + args.roomId);
            return;
        }
        game.stopFrameClock(args);
        GameManage.removeGame(args.roomId);
    },
    onCreateRoom(args: GOBERTS.ActionArgs): void {
        args.SDK.getRoomInfo().then(rommInfo => {
            args.SDK.log.error('onCreateRoom ' + rommInfo.roomStatus);
            args.SDK.log.error('onCreateRoom ' + rommInfo.roomCode);
            args.SDK.log.error('onCreateRoom ' + rommInfo.players.length);
            // 获取房间信息成功
        }).catch(err => {
            args.SDK.log.error('onCreateRoom ' + err);
            // 获取房间信息失败
        });
    },
    onRealTimeServerConnected(args: GOBERTS.ActionArgs): void {
        // do something
    },
    onRealTimeServerDisconnected(args: GOBERTS.ActionArgs): void {
        // do something
    },
    onConnect(args: GOBERTS.ActionArgs): void {
        // do something
    },
    onDisconnect(args: GOBERTS.ActionArgs): void {
        // do something
    },

    onJoin(playerInfo: GOBERTS.FramePlayerInfo, args: GOBERTS.ActionArgs): void {
        let game = GameManage.getGame(args.roomId);
        if (game === undefined) {
            return;
        }
        args.SDK.log.error('onJoin ' + playerInfo.playerId);
        game.joinPlaer(playerInfo);
        // do something
    },
    onLeave(playerInfo: GOBERTS.FramePlayerInfo, args: GOBERTS.ActionArgs): void {
        let game = GameManage.getGame(args.roomId);
        if (game === undefined) {
            return;
        }

        args.SDK.log.error('onLeave ' + playerInfo.playerId);
        game.leavePlayer(playerInfo);
        // do something
    },
    onRecvFrame(msg: GOBERTS.RecvFrameMessage | GOBERTS.RecvFrameMessage[], args: GOBERTS.ActionArgs): void {
        let unhandleFrames: GOBERTS.RecvFrameMessage[] = Array.isArray(msg) ? msg : [msg];

        unhandleFrames.forEach(message => {
            // seed frames which do not have user data
            if (!message.frameInfo || message.frameInfo.length < 1) {

                return;
            };

            // frames which have user data
            message.frameInfo.forEach((frameData: FrameInfo) => {
                let frameDataList: string[] = frameData.data;
                if (frameDataList && frameDataList.length > 0) {
                    frameDataList.forEach(res => {
                        args.SDK.log.info('frameData=' + res);
                    });
                }
            });
        });
    },
    // onRecvFromClient(args: GOBERTS.ActionArgs): void {
    //     args.SDK.getCache('example').then(value => {
    //         // 获取缓存成功
    //     }).catch(err => {
    //         // 获取缓存失败
    //     });
    // },
    onRecvFromClientV2(msg: GOBERTS.RecvFromClientInfo, args: GOBERTS.ActionArgs): void {
        // do something, onRecvFromClientV2和onRecvFromClient使用一个即可，推荐使用V2

        let gameData = JSON.parse(msg.msg);
        switch (gameData.type) {
            case "InitGame":
                handleInitGame(gameData, args);
                break;
            case "StartGame":
                handleStartGame(gameData, args);
                break;
            case "Progress":
                handleProgress(gameData, args);
                break;
            case "SlickBox":
                handleSlickCoin(msg.srcPlayer, gameData.coinIndex, args);
                break;
            default:
                break;
        }
    },
    onRoomPropertiesChange(msg: GOBERTS.UpdateRoomInfo, args: GOBERTS.ActionArgs): void {
        // do something
    },
    onStartFrameSync(args: GOBERTS.ActionArgs): void {
        // do something
    },
    onStopFrameSync(args: GOBERTS.ActionArgs): void {
        // do something
    },
    onUpdateCustomProperties(player: GOBERTS.FramePlayerPropInfo, args: GOBERTS.ActionArgs): void {
        // do something
    },
    onUpdateCustomStatus(msg: GOBERTS.PlayerStatusInfo, args: GOBERTS.ActionArgs): void {
        // do something
    },
    onRequestFrameError(error: GOBERTS.GOBEError, args: GOBERTS.ActionArgs): void {
        // do something
    },
    onRoomPropertiesChangeFailed(error: GOBERTS.GOBEError, args: GOBERTS.ActionArgs): void {
        // do something
    },
    onInstantMessageFailed(error: GOBERTS.GOBEError, args: GOBERTS.ActionArgs): void {
        // do something
    },
}

export const gobeDeveloperCode = {
    gameServer: gameServer,
    appId: 'your appId',
};


/**
 * 处理游戏初始化
 * @param gameData
 * @param args
 */
function handleInitGame(gameData: any, args: GOBERTS.ActionArgs) {
    // 初始化游戏信息，并以房间维度保存
    let gameInitInfo = <GameInitInfo>gameData;
    if (GameManage.getGame(args.roomId) !== undefined) {
        // 广播游戏进度
        Toast(args, JSON.stringify({ type: 'Toast', data: "房间已初始化" }));
        return;
    }
    let game = new Game(gameInitInfo, args.SDK.log, 30, args.roomId);
    GameManage.saveGame(args.roomId, game);
    args.SDK.getRoomInfo().then(rommInfo => {
        // 获取房间信息成功
        for (let i = 0; i < rommInfo.players.length; i++) {
            game.initPlayer(rommInfo.players[i]);
        }
    })
}

function handleStartGame(gameData: any, args: GOBERTS.ActionArgs) {
    let game = GameManage.getGame(args.roomId);
    if (game === undefined) {
        args.SDK.log.error('onStartGame game not exist' + args.roomId);
        return;
    }
    game.startGame(args);

}

/**
 * 处理加载进度
 * @param gameData
 * @param args
 */
function handleProgress(gameData: any, args: GOBERTS.ActionArgs) {
    // 广播游戏进度
    args.SDK.sendData(JSON.stringify(gameData)).then().catch(err => {
        args.SDK.log.error('sendProgressData ERROR' + err);
    });
}
/**
 * 玩家选择金币
 * @param gameData
 * @param args
 */
function handleSlickCoin(playerId: string, coinIdex: number, args: GOBERTS.ActionArgs) {
    let game = GameManage.getGame(args.roomId);
    if (game === undefined) {
        return;
    }
    game.setPlayerSlick(playerId, coinIdex, args);
}


function Toast(args: GOBERTS.ActionArgs, data: string) {
    // 广播游戏进度
    args.SDK.sendData(data).then().catch(err => {
        args.SDK.log.error('Toast' + err);
    });
}